/*
 *  test_queue.c
 *
 *  Created on: May 16, 2011
 *  Author: Nicholas Swartzendruber
 *  Non-test code obtained from Sergiy Kulyk.
 */

#include <stdio.h>
#include <CUnit/Basic.h>
#include "../src/queue.h"
#include "../src/timer.h"

/* The suite initialization function.
 * Opens the temporary file used by the tests.
 * Returns zero on success, non-zero otherwise.
 */
int init_suite1(void) {
    /* Here we put code that will run before
     * the entire test suit runs. */
    return 0;
}


/* The suite cleanup function.
 * Closes the temporary file used by the tests.
 * Returns zero on success, non-zero otherwise.
 */
int clean_suite1(void) {
    /* Here we put code that will run after
     * the entire test suit runs. */
    return 0;
}

/****** Test functions ********/

/**
 * Tests enqueue and dequeue for int values.
 */
void test_enqueue_dequeue_int(void) {
	int i;
	int deq;
	int test_size = 10;
	Queue q = queue_CreateQueue(test_size);

	//Add numbers, the size should match.
	for (i=0; i<test_size; i++) {
		queue_Enqueue(i, q);
		CU_ASSERT(q->Size == i + 1);
	}

	//Remove numbers, they should match expected.
	for(i = 0; i < test_size; i++) {
		deq = queue_FrontAndDequeue(q);
		CU_ASSERT(deq == i);
		CU_ASSERT(q->Size == test_size - 1 - i);
	}

	queue_DisposeQueue(q);
}

/**
 * Tests enqueue and dequeue a pointer to a struct.
 */
void test_enqueue_dequeue_struct(void) {
	timer tmp;
	timer t = timer_initialize();
	int test_size = 10;
	Queue q = queue_CreateQueue(test_size);

	//Enqueue the timer.
	queue_Enqueue(t, q);
	CU_ASSERT(q->Size == 1);

	//Dequeue the timer.
	tmp = queue_FrontAndDequeue(q);
	CU_ASSERT(tmp == t);

	queue_DisposeQueue(q);
}

/**
 * Tests the isEmpty function for the queue.
 */
void test_isEmpty(void) {
	int test_size = 10;
	Queue q = queue_CreateQueue(test_size);

	CU_ASSERT(queue_IsEmpty(q));
	queue_Enqueue(1, q);
	CU_ASSERT(!queue_IsEmpty(q));

	queue_DisposeQueue(q);
}

/**
 * Tests the isFull function for the queue.
 */
void test_isFull(void) {
	int test_size = 1;
	Queue q = queue_CreateQueue(test_size);

	CU_ASSERT(!queue_IsFull(q));
	queue_Enqueue(1, q);
	CU_ASSERT(queue_IsFull(q));

	queue_DisposeQueue(q);
}

/******  End Test functions ********/
int main(void) {

    CU_pSuite pSuite = NULL;

    /* initialize the CUnit test registry */
    if (CUE_SUCCESS != CU_initialize_registry())
        return CU_get_error();

    /* add a suite to the registry */
    pSuite = CU_add_suite("Queue_Suite", init_suite1, clean_suite1);
    if (NULL == pSuite) {
        CU_cleanup_registry();
        return CU_get_error();
    }

    /* add the tests to the suite */
    if ((NULL == CU_add_test(pSuite, "test for enqueue and dequeue int values.", test_enqueue_dequeue_int)) ||
        (NULL == CU_add_test(pSuite, "test for enqueue and dequeue on struct pointers.", test_enqueue_dequeue_struct)) ||
        (NULL == CU_add_test(pSuite, "test for IsEmpty() on queue.", test_isEmpty)) ||
        (NULL == CU_add_test(pSuite, "test for IsFull() on queue.", test_isFull)))
    {
        CU_cleanup_registry();
        return CU_get_error();
    }

    /* Run all tests using the CUnit Basic interface */
    CU_basic_set_mode(CU_BRM_VERBOSE);
    CU_basic_run_tests();
    CU_cleanup_registry();
    return CU_get_error();
}
